package com.soft.knowledge.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.soft.knowledge.entity.*;
import com.soft.knowledge.mapper.ContentMapper;
import com.soft.knowledge.mapper.DocCustomMapper;
import com.soft.knowledge.mapper.DocMapper;
import com.soft.knowledge.mapper.VoteMapper;
import com.soft.knowledge.req.DocQueryReq;
import com.soft.knowledge.req.DocSaveReq;
import com.soft.knowledge.req.VoteReq;
import com.soft.knowledge.resp.DocQueryResp;
import com.soft.knowledge.resp.PageResp;
import com.soft.knowledge.utils.CopyUtil;
import com.soft.knowledge.utils.SnowFlake;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.List;

/**
 * 电子书(Doc)表服务实现类
 *
 * @author makejava
 * @since 2022-11-19 13:17:14
 */
@Service
public class DocService {
    private static final Logger LOG = LoggerFactory.getLogger(DocService.class);
    @Resource
    private DocMapper docMapper;

    @Resource
    private DocCustomMapper docCustomMapper;

    @Resource
    private VoteMapper voteMapper;

    @Resource
    private SnowFlake snowFlake;

    @Resource
    private ContentMapper contentMapper;

//    @Resource
//    private RocketMQTemplate rocketMQTemplate;

    @Resource
    private WebSocketService webSocketService;
    /**
     * DocReq：请求参数列表
     * DocResp: 返回参数列表
     * 最好不要出现Doc类
     * @param req
     * @return
     */
    public PageResp<DocQueryResp> list(DocQueryReq req){

        DocExample example = new DocExample();
        DocExample.Criteria criteria = example.createCriteria();
        //动态sql
        if (!ObjectUtils.isEmpty(req.getName())){
            criteria.andNameLike("%"+req.getName()+"%");
        }
        criteria.andEbookIdEqualTo(req.getEbookId());
        //PageHelper和查询的list放到一起
        PageHelper.startPage(req.getPage(),req.getSize());
        List<Doc> docList = docMapper.selectByExample(example);
        PageInfo<Doc> pageInfo = new PageInfo<>(docList);
        LOG.info("总条数：{}", pageInfo.getTotal());
        LOG.info("总页数：{}", pageInfo.getPages());
//        List<DocResp> respList = new ArrayList<>();
//        for(Doc doc: docList){
////            DocResp resp = new DocResp();
////            BeanUtils.copyProperties(doc, resp);
//            respList.add( CopyUtil.copy(doc, DocResp.class));
//        }

        PageResp<DocQueryResp> pageResp = new PageResp<>();
        pageResp.setTotal(pageInfo.getTotal());
        pageResp.setList(CopyUtil.copyList(docList, DocQueryResp.class));
        return pageResp;
    }
    public List<DocQueryResp> all(Long ebookId){

        DocExample example = new DocExample();
        example.createCriteria().andEbookIdEqualTo(ebookId);
        example.setOrderByClause("sort asc");
        List<Doc> docList = docMapper.selectByExample(example);

        return CopyUtil.copyList(docList, DocQueryResp.class);
    }

    /**
     * 保存或新增
     * 对两张表进行修改的业务要加上事务
     */
    @Transactional(rollbackFor = Exception.class)
    public void save(DocSaveReq req){
        Doc doc = CopyUtil.copy(req, Doc.class);
        Content content = CopyUtil.copy(req, Content.class);
        if(ObjectUtils.isEmpty(doc.getId())){
            //新增
            doc.setId(snowFlake.nextId());
            doc.setViewCount(0);
            doc.setVoteCount(0);
            try {
                if(docMapper.insert(doc) == 0) {
                    throw new Exception("【doc】插入数据异常！");
                }

                content.setId(doc.getId());
                if(contentMapper.insert(content) == 0) {
                    throw new Exception("【content】插入数据异常！");
                }
            } catch (Exception e){
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }

        } else {
            //更新
            docMapper.updateByPrimaryKey(doc);
            int count = contentMapper.updateByPrimaryKeyWithBLOBs(content);
            if (count == 0){
                contentMapper.insert(content);
            }
        }
    }

    public void delete(Long id) {
        docMapper.deleteByPrimaryKey(id);
    }
    public void delete(List<String> ids) {
        DocExample example = new DocExample();
        DocExample.Criteria criteria = example.createCriteria();
        criteria.andIdIn(ids);
        docMapper.deleteByExample(example);
    }

    public String findContent(Long id) {
        Content content = contentMapper.selectByPrimaryKey(id);
        //文档浏览次数加一
        docCustomMapper.increaseViewCount(id);

        if (ObjectUtils.isEmpty(content)) {
            return "";
        } else {
            return content.getContent();
        }
    }

    public void vote(VoteReq req) {
        Vote vote = CopyUtil.copy(req, Vote.class);
        if (req.getOperation().equals("add")) {
            voteMapper.insert(vote);
            docCustomMapper.increaseVoteCount(req.getInfoId());

            //异步推送点赞消息，要实现同一个方法中的不同部分代码的异步化，要把被异步化的代码写到另外一个类中
            Doc docDb = docMapper.selectByPrimaryKey(req.getInfoId());
            String logId = MDC.get("LOG_ID");
            webSocketService.sendInfo("【" + docDb.getName() + "】被点赞！", logId);
//            rocketMQTemplate.convertAndSend("VOTE_TOPIC", "【" + docDb.getName() + "】被点赞！");

        } else {
            VoteExample example = new VoteExample();
            VoteExample.Criteria criteria = example.createCriteria();
            criteria.andInfoIdEqualTo(req.getInfoId())
                    .andUserIdEqualTo(req.getUserId());
            voteMapper.deleteByExample(example);

            docCustomMapper.decreaseVoteCount(req.getInfoId());
        }

    }

    public void updateEbookInfo() {
        docCustomMapper.updateEbookInfo();
    }

}